home *** CD-ROM | disk | FTP | other *** search
- /*
-
- File: FindOpenDocFolder.c
-
- Contents: Utility routines for finding OpenDoc folders by looking
- in several places.
-
- Owned by: Troy Gaul
-
- Copyright: © 1996 Apple Computer, Inc. All rights reserved.
-
- Change History (most recent first):
-
- <1> 12/19/96 TJ first checked in
- 12/18/96 TAG Created.
-
- */
-
- #ifndef _FINDOPENDOCFOLDER_
- #include "FindOpenDocFolder.h"
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __SCRIPT__
- #include <Script.h>
- #endif
-
- //------------------------------------------------------------------------------
- // Constants
- //------------------------------------------------------------------------------
- enum
- {
- kOpenDocFoldersFLDxResourceID = 128
- };
-
- //------------------------------------------------------------------------------
- // DirIDFromSpecialPath (from AtomUtils)
- //------------------------------------------------------------------------------
- static long
- DirIDFromSpecialPath(StringPtr path, short vRefNum)
- {
- StringPtr s;
- OSType folderType;
- short foundVrefNum;
- long foundDirID;
- OSErr err;
-
- for (s = path ; s[0] != '-' ; s++) // step over 'spcl'
- ;
-
- BlockMove(&s[1], &folderType, 4);
- err = FindFolder(vRefNum, folderType, kDontCreateFolder, &foundVrefNum, &foundDirID);
-
- return foundDirID;
- }
-
- //------------------------------------------------------------------------------
- // PathFromSpecialPath (from AtomUtils)
- //------------------------------------------------------------------------------
- static void
- PathFromSpecialPath(StringPtr inSpecialPath, StringPtr outPathStorage)
- {
- StringPtr s;
- for ( s = inSpecialPath ; *s != ':' ; s++ )
- ;
-
- outPathStorage[0] = inSpecialPath[0] - (s - inSpecialPath) +1; // length of rest of string
- BlockMove(s, &(outPathStorage[1]), outPathStorage[0]);
- }
-
- //------------------------------------------------------------------------------
- // GetNextFLDxEntry
- //------------------------------------------------------------------------------
- typedef struct FLDxEntry {
- OSType folderType;
- short version;
- Str255 folderName;
- } FLDxEntry;
-
- static Ptr
- GetNextFLDxEntry(Ptr inPointer, FLDxEntry* entry)
- {
- char* ptr = inPointer;
-
- entry->folderType = *(OSType*) ptr; // folder type
- ptr += sizeof(OSType);
-
- entry->version = *(short*) ptr; // version
- ptr += sizeof(short);
-
- ptr += sizeof(Byte); // high byte of length
-
- entry->folderName[0] = *(unsigned char*) ptr;
- ptr += sizeof(unsigned char);
-
- BlockMoveData(ptr, entry->folderName + 1, entry->folderName[0]);
- ptr += entry->folderName[0];
-
- if ((entry->folderName[0] % 2) == 1) // word align it.
- ptr += 1;
-
- return ptr;
- }
-
- //------------------------------------------------------------------------------
- // GetPathFromFLDxResource
- //------------------------------------------------------------------------------
- static OSErr
- GetPathFromFLDxResource(short inResID, OSType inFolderType, StringPtr outFolderPath)
- {
- OSErr err = noErr;
- Boolean found = false;
- Handle folderRes;
- long size;
- Ptr ptr, end;
- FLDxEntry entry;
-
- folderRes = Get1Resource('fld#', inResID);
- if (folderRes == NULL)
- {
- err = ResError();
- if (err) return err;
- return resNotFound;
- }
-
- size = GetHandleSize(folderRes);
- ptr = *folderRes;
- end = ptr + size;
-
- while (ptr < end)
- {
- ptr = GetNextFLDxEntry(ptr, &entry);
-
- if (entry.folderType == inFolderType)
- {
- found = true;
- break;
- }
- }
-
- if (found)
- BlockMoveData(entry.folderName, outFolderPath, entry.folderName[0] + 1);
- else
- err = fnfErr;
-
- ReleaseResource(folderRes); // !!!!! this is fine as long as noone else is using it.
-
- return err;
- }
-
- //------------------------------------------------------------------------------
- // GetFolderFromOpenDocFoldersFLDx
- //------------------------------------------------------------------------------
- static OSErr
- GetFolderFromOpenDocFoldersFLDx(short inVRefNum, OSType inFolderType,
- StringPtr outFolderPath)
- {
- OSErr err = noErr;
- short sysVRefNum;
- long sysDirID;
- FSSpec foldersFileSpec;
- short saveResFile = CurResFile();
- short resFileID;
-
- // Find the System Folder.
- err = FindFolder(inVRefNum, kSystemFolderType, kDontCreateFolder, &sysVRefNum, &sysDirID);
- if (err) return err;
-
- // Find the invisible OpenDocFolder• file.
- err = FSMakeFSSpec(sysVRefNum, sysDirID, "\pOpenDocFolders•", &foldersFileSpec);
- if (err) return err;
-
- // Open the resource file.
- resFileID = FSpOpenResFile(&foldersFileSpec, fsRdPerm);
- err = noErr;
- if (resFileID == -1)
- err = ResError();
-
- // Get the pathname from the resource.
- if (err == noErr)
- {
- UseResFile(resFileID); // !!!!! not sure this is needed
- err = GetPathFromFLDxResource(kOpenDocFoldersFLDxResourceID,
- inFolderType, outFolderPath);
- CloseResFile(resFileID);
- }
-
- UseResFile(saveResFile);
-
- return err;
- }
-
- //——————————————————————————————————————————————————————————————————————————————
- // GetDirectoryDirID
- //——————————————————————————————————————————————————————————————————————————————
- static OSErr
- GetDirectoryDirID(const FSSpec* inDirectory, long *outDirID)
- {
- CInfoPBRec pb; // parameter block used to access files
- OSErr err = noErr;
-
- *outDirID = 0;
-
- // Get the directory ID of this directory (rather than its parent)
- pb.dirInfo.ioVRefNum = inDirectory->vRefNum;
- pb.dirInfo.ioDrDirID = inDirectory->parID;
- pb.dirInfo.ioNamePtr = (StringPtr) inDirectory->name;
- pb.dirInfo.ioFDirIndex = 0; // get directory id of _this_ directory
-
- err = PBGetCatInfoSync(&pb);
- if (err) return err;
-
- *outDirID = pb.dirInfo.ioDrDirID;
- return err;
- }
-
- //------------------------------------------------------------------------------
- // FindOpenDocFolder
- //------------------------------------------------------------------------------
- pascal OSErr
- FindOpenDocFolder(short inVRefNum, OSType inFolderType, Boolean inCreateFolder,
- short* outFoundVRefNum, long* outFoundDirID)
- {
- OSErr err = noErr;
- Str255 specialPath;
- Str255 path;
- FSSpec foundFolderSpec;
- long specialDirID;
-
- // First, try FindFolder to see if it's now supported.
- err = FindFolder(inVRefNum, inFolderType, inCreateFolder, outFoundVRefNum,
- outFoundDirID);
- if (err != fnfErr)
- return err;
-
- // FindFolder didn't work, so look for the invisible file.
- *outFoundVRefNum = inVRefNum;
-
- err = GetFolderFromOpenDocFoldersFLDx(inVRefNum, inFolderType, specialPath);
-
- // Problem finding/reading invisible file, look in the resoruce chain:
- if (err)
- err = GetPathFromFLDxResource(kOpenDocFLDxResourceID, inFolderType, specialPath);
- if (err) return err;
-
- if ( specialPath[1] != ':' ) // Found SpecialFolder
- {
- specialDirID = DirIDFromSpecialPath(specialPath, inVRefNum);
-
- // Using the relative path, find the folder.
- PathFromSpecialPath(specialPath, path);
- }
- else
- {
- // This was a target pathname like ':Folder 1:FileName', no chopping necessary
-
- BlockMove(&specialPath, path, specialPath[0] + 1);
-
- // The target was off of the root, not the blessed, so adjust the dirID we'll look for the file
- // to the root of the target volume.
-
- specialDirID = 0;
- }
-
- // Get the directory specified at the front of the special path.
- err = FSMakeFSSpec(*outFoundVRefNum, specialDirID, path, &foundFolderSpec);
-
- // It might not be there.
- if (err == fnfErr)
- {
- // If not, we might need to create it.
- if (inCreateFolder)
- err = FSpDirCreate(&foundFolderSpec, smSystemScript, outFoundDirID);
- }
- else if (err == noErr)
- {
- // If so, get it's directory ID to return.
- GetDirectoryDirID(&foundFolderSpec, outFoundDirID);
- }
-
- return err;
- }
-
- //------------------------------------------------------------------------------
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-